package com.cloudsea.yunhaistores.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.extra.qrcode.QrCodeUtil;
import cn.hutool.extra.qrcode.QrConfig;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.cloudsea.yunhaistores.dto.TableAddDTO;
import com.cloudsea.yunhaistores.entity.MerchantUsers;
import com.cloudsea.yunhaistores.entity.Stores;
import com.cloudsea.yunhaistores.entity.Tables;
import com.cloudsea.yunhaistores.mapper.MerchantUsersMapper;
import com.cloudsea.yunhaistores.mapper.StoresMapper;
import com.cloudsea.yunhaistores.mapper.TablesMapper;
import com.cloudsea.yunhaistores.service.TableService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.OutputStream;
import java.time.LocalDateTime;
import java.util.List;

@Service
public class TableServiceImpl implements TableService {

    @Autowired
    private TablesMapper tablesMapper;

    @Autowired
    private Snowflake snowflake;

    @Autowired
    private MerchantUsersMapper merchantUsersMapper;

    @Autowired
    private StoresMapper storesMapper;

    @Value("${app.domain}")
    private String appDomain;

    @Override
    public Tables addTable(TableAddDTO dto) {
        Tables newTable = new Tables();
        long tableId = snowflake.nextId();
        newTable.setId(tableId);
        newTable.setStoreId(dto.getStoreId());
        newTable.setTableName(dto.getTableName());
        // 预生成二维码内容并存入数据库，这是一个优化
        newTable.setQrCodeContent(appDomain + "/menu?tableId=" + tableId);
        newTable.setCreatedAt(LocalDateTime.now());
        newTable.setUpdatedAt(LocalDateTime.now());

        tablesMapper.insert(newTable);
        return newTable;
    }

    @Override
    public List<Tables> listTablesByStoreId(Long storeId) {
        QueryWrapper<Tables> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("store_id", storeId);
        return tablesMapper.selectList(queryWrapper);
    }

    @Override
    public void generateQrCode(Long tableId, OutputStream outputStream) {
        Tables table = tablesMapper.selectById(tableId);
        if (table == null || table.getQrCodeContent() == null) {
            throw new RuntimeException("桌台不存在或二维码内容未生成");
        }

        QrConfig config = new QrConfig(300, 300);
        config.setMargin(1);
        QrCodeUtil.generate(table.getQrCodeContent(), config, "png", outputStream);
    }

    @Override
    public void clearTable(Long tableId) {
        // 1. 查询桌台信息
        Tables table = tablesMapper.selectById(tableId);
        if (table == null) {
            throw new RuntimeException("桌台不存在");
        }

        // =================================================================
        //                【核心安全校验逻辑】
        // =================================================================

        // 2. 获取当前操作员（服务员）的信息
        long loginId = StpUtil.getLoginIdAsLong();
        MerchantUsers currentUser = merchantUsersMapper.selectById(loginId);
        if (currentUser == null || currentUser.getMerchantId() == null) {
            // 如果在Token有效的情况下，在数据库中找不到用户，这是一个严重问题
            throw new RuntimeException("操作员信息异常，权限校验失败");
        }
        Long operatorMerchantId = currentUser.getMerchantId();

        // 3. 获取桌台所属的商户ID
        // a. 先通过桌台的 store_id 找到门店信息
        Stores store = storesMapper.selectById(table.getStoreId());
        if (store == null) {
            throw new RuntimeException("桌台所属的门店信息不存在，数据异常");
        }
        Long tableMerchantId = store.getMerchantId();

        // 4. 比对操作员和桌台的商户ID是否一致
        if (!operatorMerchantId.equals(tableMerchantId)) {
            // 如果不一致，说明是跨店操作，立即拒绝并抛出异常
            throw new SecurityException("无权操作不属于自己商户的桌台");
        }

        // =================================================================
        //                【权限校验通过，继续执行原业务】
        // =================================================================

        // 5. 更新桌台状态
        UpdateWrapper<Tables> updateWrapper = new UpdateWrapper<>();
        updateWrapper
                .eq("id", tableId) // 指定更新条件 WHERE id = ?
                .set("status", 0) // 设置 status = 0
                .set("current_session_id", null); // 明确地将 current_session_id 设置为 NULL

        // 6. 使用带Wrapper的update方法执行更新
        tablesMapper.update(null, updateWrapper);



        // 5. 【后续扩展】可以清理 shopping_carts 表中属于该会话的旧数据
        //    String expiredSessionId = table.getCurrentSessionId();
        //    if(expiredSessionId != null){
        //        shoppingCartsMapper.delete(new QueryWrapper<ShoppingCarts>().eq("session_id", expiredSessionId));
        //    }
    }
}